// hooks/useRequest/plugin.ts
import { RequestOptions, RequestPlugin } from './types';

// 插件列表
const plugins: RequestPlugin[] = [];

/**
 * 注册插件
 * @param plugin 插件对象
 */
export const registerPlugin = (plugin: RequestPlugin): void => {
    plugins.push(plugin);
};

/**
 * 移除插件
 * @param plugin 插件对象
 */
export const removePlugin = (plugin: RequestPlugin): void => {
    const index = plugins.indexOf(plugin);
    if (index !== -1) {
        plugins.splice(index, 1);
    }
};

/**
 * 清除所有插件
 */
export const clearPlugins = (): void => {
    plugins.length = 0;
};

/**
 * 应用初始化钩子
 * @param options 请求配置
 * @returns 处理后的请求配置
 */
export const applyInitHooks = (options: RequestOptions): RequestOptions => {
    return plugins.reduce((opts, plugin) => {
        if (plugin.onInit) {
            return plugin.onInit(opts);
        }
        return opts;
    }, options);
};

/**
 * 应用请求前钩子
 * @param options 请求配置
 * @returns 处理后的请求配置
 */
export const applyRequestHooks = async (options: RequestOptions): Promise<RequestOptions> => {
    let opts = options;

    for (const plugin of plugins) {
        if (plugin.onRequest) {
            const result = plugin.onRequest(opts);
            if (result instanceof Promise) {
                opts = await result;
            } else {
                opts = result;
            }
        }
    }

    return opts;
};

/**
 * 应用请求成功钩子
 * @param data 响应数据
 * @param options 请求配置
 * @returns 处理后的响应数据
 */
export const applySuccessHooks = async <T>(data: T, options: RequestOptions): Promise<T> => {
    let result = data;

    for (const plugin of plugins) {
        if (plugin.onSuccess) {
            const pluginResult = plugin.onSuccess(result, options);
            if (pluginResult instanceof Promise) {
                result = await pluginResult;
            } else {
                result = pluginResult;
            }
        }
    }

    return result;
};

/**
 * 应用请求错误钩子
 * @param error 错误对象
 * @param options 请求配置
 * @returns 处理后的错误对象，如果返回undefined则表示错误已被处理
 */
export const applyErrorHooks = async (error: Error, options: RequestOptions): Promise<Error | undefined> => {
    let currentError: Error | undefined = error;

    for (const plugin of plugins) {
        if (plugin.onError && currentError) {
            const result = await plugin.onError(currentError, options);
            currentError = result || undefined;
        }
    }

    return currentError;
};

/**
 * 应用请求完成钩子
 * @param options 请求配置
 */
export const applyFinallyHooks = async (options: RequestOptions): Promise<void> => {
    for (const plugin of plugins) {
        if (plugin.onFinally) {
            const result = plugin.onFinally(options);
            if (result instanceof Promise) {
                await result;
            }
        }
    }
};

/**
 * 创建一个基础认证插件
 * @param getToken 获取token的函数
 * @returns 认证插件
 */
export const createAuthPlugin = (getToken: () => string | null): RequestPlugin => {
    return {
        onRequest: (options: RequestOptions) => {
            if (options.withToken !== false) {
                const token = getToken();
                if (token) {
                    return {
                        ...options,
                        headers: {
                            ...options.headers,
                            Authorization: `Bearer ${token}`
                        }
                    };
                }
            }
            return options;
        }
    };
};

/**
 * 创建一个请求日志插件
 * @returns 日志插件
 */
export const createLoggerPlugin = (): RequestPlugin => {
    return {
        onRequest: (options: RequestOptions) => {
            console.log(`[Request] ${options.method || 'GET'} ${options.data ? JSON.stringify(options.data) : ''}`);
            return options;
        },
        onSuccess: <T>(data: T, options: RequestOptions) => {
            console.log(`[Response] Success:`, data);
            return data;
        },
        onError: (error: Error, options: RequestOptions) => {
            console.error(`[Response] Error:`, error);
            return error;
        }
    };
};

/**
 * 创建一个响应处理插件
 * @param successCode 成功状态码
 * @param getErrorMessage 获取错误信息的函数
 * @returns 响应处理插件
 */
export const createResponsePlugin = <T extends { code: number | string, msg?: string, message?: string }>(
    successCode: number | string | (number | string)[],
    getErrorMessage?: (response: T) => string
): RequestPlugin => {
    const isSuccess = (code: number | string): boolean => {
        if (Array.isArray(successCode)) {
            return successCode.includes(code);
        }
        return code === successCode;
    };

    return {
        onSuccess: <R>(data: any, options: RequestOptions) => {
            if (data && typeof data === 'object' && 'code' in data) {
                const response = data as T;

                if (isSuccess(response.code)) {
                    return data;
                } else {
                    const errorMessage = getErrorMessage
                        ? getErrorMessage(response)
                        : response.msg || response.message || '请求失败';

                    throw new Error(errorMessage);
                }
            }
            return data;
        }
    };
}; 